package com.migu.spms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.migu.spms.common.StringUtil;
import com.migu.spms.constant.Constant;
import com.migu.spms.dao.entity.ChangeHistoryCriteria;
import com.migu.spms.dao.entity.FunctionRequireCriteria;
import com.migu.spms.dao.entity.FunctionRequireDO;
import com.migu.spms.dao.entity.FunctionRequirementCorrelationRequireCriteria;
import com.migu.spms.dao.entity.RequireAttachmentCriteria;
import com.migu.spms.dao.entity.RequireTypeTreeDO;
import com.migu.spms.dao.entity.RequireUserCriteria;
import com.migu.spms.dao.entity.SubParentRequireCriteria;
import com.migu.spms.dao.inf.IBaseLineDO;
import com.migu.spms.dao.inf.IChangeHistoryDO;
import com.migu.spms.dao.inf.IFunctionRequireDO;
import com.migu.spms.dao.inf.IFunctionRequirementCorrelationRequireDO;
import com.migu.spms.dao.inf.IRequireAttachmentDO;
import com.migu.spms.dao.inf.IRequireTypeTreeDO;
import com.migu.spms.dao.inf.IRequireUserDO;
import com.migu.spms.dao.inf.ISubParentRequireDO;
import com.migu.spms.service.data.User;
import com.migu.spms.service.inf.ICreateRequireService;
import com.migu.spms.service.inf.IFunctionFlowService;
import com.migu.spms.service.inf.ISequenceCreateService;
import com.migu.spms.utils.CodeCreateUtil;
import com.migu.spms.utils.PropertiesCopyUtil;
import com.migu.spms.utils.RequestValidateUtil;
import com.migu.spms.utils.exception.ServiceException;
import com.migu.spms.webapi.data.AvailableBaselineQueryRequest;
import com.migu.spms.webapi.data.CreateRequireRequest;
import com.migu.spms.webapi.data.base.BaseLine;

/**
 * 
* 项目名称:  SPMS需求管理
* 包:        com.migu.spms.service.impl 
* 类名称:    CreateRequireServiceImpl.java
* 类描述:    创建需求业务实现类
* 创建人:    fw  
* 创建时间:  2017年6月19日 下午2:40:36
 */
@Transactional
@Component(value = "createRequireService")
public class CreateRequireServiceImpl implements ICreateRequireService {
    private static Logger logger = LoggerFactory.getLogger(CreateRequireServiceImpl.class);

    @Resource(name = "IFunctionRequireDO")
    private IFunctionRequireDO functionRequireDAO;
    @Resource(name = "IRequireAttachmentDO")
    private IRequireAttachmentDO requireAttachmentDAO;
    @Resource(name = "ISubParentRequireDO")
    private ISubParentRequireDO subParentRequireDAO;
    @Resource(name = "IFunctionRequirementCorrelationRequireDO")
    private IFunctionRequirementCorrelationRequireDO functionRequirementCorrelationRequireDAO;
    @Resource(name = "IBaseLineDO")
    private IBaseLineDO baseLineDAO;
    @Resource(name = "IRequireUserDO")
    private IRequireUserDO requireUserDAO;
    @Resource(name = "IRequireTypeTreeDO")
    private IRequireTypeTreeDO requireTypeTreeDAO;
    @Resource(name = "sequenceService")
    private ISequenceCreateService sequenceService;
    @Resource(name = "functionFlowServiceImpl")
    private IFunctionFlowService functionFlowService;
    @Resource(name = "IChangeHistoryDO")
    private IChangeHistoryDO changeHistoryDAO;

    /**
     * 新建需求
    * @param createRequireRequest
    * @param user
    * @return
    * @throws Exception
     */
    @Override
    public Boolean create(CreateRequireRequest createRequireRequest, User user) throws Exception {
        RequestValidateUtil.validateCreateRequireRequest(createRequireRequest);
        FunctionRequireCriteria functionRequireCriteria = PropertiesCopyUtil.parse(createRequireRequest,
                FunctionRequireCriteria.class);
        functionRequireCriteria.setCreateTime(new Date());
        functionRequireCriteria.setRequireId(CodeCreateUtil
                .createRequireId(createRequireRequest.getProjectId().longValue(), sequenceService.getRequireNumber()));
        functionRequireCriteria.setStatus(Constant.flowStatus.NEWING);
        functionRequireCriteria.setCurrentHandlerId(createRequireRequest.getDevelopResponsibleId());
        functionRequireCriteria.setCurrentHandlerName(createRequireRequest.getDevelopResponsibleName());
        functionRequireCriteria.setIsBaseLine(Constant.LogicVariable.NO_INT);
        if (null != createRequireRequest.getParentId()) {
            functionRequireCriteria.setIsSubRequire(Constant.LogicVariable.YES_INT);
            FunctionRequireDO functionRequireDO = functionRequireDAO
                    .selectByPrimaryKey(createRequireRequest.getParentId());
            if (null == functionRequireDO) {
                logger.error(
                        CodeCreateUtil.createLogMessage("CreateRequireServiceImpl.create", "新建需求[根据父需求id查询父需求为空]"));
                throw new ServiceException("新建需求失败，请重试！");
            }
            if (null == createRequireRequest.getRequireTypeId()) {
                functionRequireCriteria.setRequireTypeId(functionRequireDO.getRequireTypeId());
                functionRequireCriteria.setRequireTypeName(functionRequireDO.getRequireTypeName());

            }
            if (StringUtil.isEmpty(createRequireRequest.getBaselineVersion())) {
                functionRequireCriteria.setBaselineVersion(functionRequireDO.getBaselineVersion());
            }
        } else {
            functionRequireCriteria.setIsSubRequire(Constant.LogicVariable.NO_INT);
            if (null == createRequireRequest.getRequireTypeId()) {
                RequireTypeTreeDO requireTypeTreeDO = requireTypeTreeDAO
                        .selectByPrimaryKey(Long.valueOf(Constant.typeTree.TWO));
                functionRequireCriteria.setRequireTypeId(requireTypeTreeDO.getId());
                functionRequireCriteria.setRequireTypeName(requireTypeTreeDO.getName());
            }
        }
        // functionRequireCriteria.setIsParentRequire(Constant.LogicVariable.NO_INT);
        functionRequireDAO.insertSelective(functionRequireCriteria);
        if (null == functionRequireCriteria.getId()) {
            logger.error(CodeCreateUtil.createLogMessage("CreateRequireServiceImpl.create", "新建需求[插入需求主表信息后返回主键id为空]"));
            throw new ServiceException("新建需求失败，请重试！");
        }
        // 插入业务需求信息到关联表
        // if (null != createRequireRequest.getRelativeBusinessRequireId()) {
        // FunctionRequirementCorrelationRequireCriteria
        // functionRequirementCorrelationRequireCriteria = new
        // FunctionRequirementCorrelationRequireCriteria();
        // functionRequirementCorrelationRequireCriteria
        // .setFunctionRequireId(String.valueOf(functionRequireCriteria.getId().longValue()));
        // functionRequirementCorrelationRequireCriteria
        // .setCorrelationRequireId(functionRequireCriteria.getRelativeBusinessRequireId());
        // functionRequirementCorrelationRequireCriteria.setIdentifi(Constant.IsBussinessRequirement.YES);
        // functionRequirementCorrelationRequireDAO.insertSelective(functionRequirementCorrelationRequireCriteria);
        // }
        insertUser(createRequireRequest, Constant.Role.DEVELOPER, functionRequireCriteria.getId());
        insertUser(createRequireRequest, Constant.Role.TESTER, functionRequireCriteria.getId());
        List<RequireAttachmentCriteria> attachments = createRequireRequest.getAttachments();
        if (null != attachments && attachments.size() > 0) {
            for (RequireAttachmentCriteria requireAttachmentCriteria : attachments) {
                requireAttachmentCriteria.setFunctionRequireId(functionRequireCriteria.getId());
                requireAttachmentCriteria.setUploaderId(Long.valueOf(user.getUserId()));
                requireAttachmentCriteria.setUploaderName(user.getUserName());
                requireAttachmentCriteria.setUploadTime(new Date());
            }
            requireAttachmentDAO.batchInsert(attachments);
        }
        if (null != createRequireRequest.getParentId()) {
            SubParentRequireCriteria subParentRequireCriteria = new SubParentRequireCriteria();
            subParentRequireCriteria.setParentRequireId(createRequireRequest.getParentId());
            subParentRequireCriteria.setSubRequireId(functionRequireCriteria.getId());
            subParentRequireDAO.insertSelective(subParentRequireCriteria);
            // updateParentRequireFlag(createRequireRequest);
        }
        insertOperateHistory(createRequireRequest, functionRequireCriteria);
        functionFlowService.startProcessFlow(functionRequireCriteria.getId(), user);
        return true;
    }

    private void insertUser(CreateRequireRequest createRequireRequest, Long roleId, Long functionRequireId) {
        List<com.migu.spms.webapi.data.User> users = null;
        if (Constant.Role.DEVELOPER.longValue() == roleId.longValue()) {
            users = createRequireRequest.getDevelopers();
        } else if (Constant.Role.TESTER.longValue() == roleId.longValue()) {
            users = createRequireRequest.getTesters();
        }
        if (null != users && users.size() > 0) {
            List<RequireUserCriteria> requireUserCriterias = new ArrayList<>();
            for (com.migu.spms.webapi.data.User user : users) {
                RequireUserCriteria requireUserCriteria = PropertiesCopyUtil.parse(user, RequireUserCriteria.class);
                requireUserCriteria.setFunctionRequireId(functionRequireId);
                requireUserCriteria.setRoleId(roleId);
                requireUserCriterias.add(requireUserCriteria);
            }
            requireUserDAO.batchInsert(requireUserCriterias);
        }
    }

    private void insertOperateHistory(CreateRequireRequest createRequireRequest,
            FunctionRequireCriteria functionRequireCriteria) {
        ChangeHistoryCriteria changeHistoryCriteria = new ChangeHistoryCriteria();
        changeHistoryCriteria.setBaselineVersion(createRequireRequest.getBaselineVersion());
        changeHistoryCriteria.setFunctionRequireId(functionRequireCriteria.getId());
        changeHistoryCriteria.setCreateId(Long.valueOf(createRequireRequest.getCreatorId()));
        changeHistoryCriteria.setCreateName(createRequireRequest.getCreatorName());
        changeHistoryCriteria.setCreateTime(new Date());
        changeHistoryCriteria.setIsPermit(Constant.LogicVariable.NO_INT.toString());
        changeHistoryCriteria.setIsDetails(Constant.LogicVariable.NO_INT.toString());
        // if (null != createRequireRequest.getParentId()) {
        // changeHistoryCriteria.setOperateType(Constant.flowOperate.CREATE_NEW_REQUIREMENT);
        // // changeHistoryCriteria.setRemark(
        // //
        // CodeCreateUtil.createRequireRemark(String.valueOf(createRequireRequest.getParentId().longValue())));
        // changeHistoryCriteria.setRemark(CodeCreateUtil.createRequireRemark(null));
        // } else {
        // changeHistoryCriteria.setOperateType(Constant.flowOperate.CREATE_NEW_REQUIREMENT);
        // changeHistoryCriteria.setRemark(CodeCreateUtil.createRequireRemark(null));
        // }
        if (StringUtil.isEmpty(createRequireRequest.getBaselineVersion())) {
            changeHistoryCriteria.setOperateType(Constant.flowOperate.CREATE_NEW_REQUIREMENT);
//        } else {
//            changeHistoryCriteria.setOperateType(createRequireRequest.getBaselineVersion());
        }
        changeHistoryCriteria.setRemark(CodeCreateUtil.createRequireRemark(null));
        changeHistoryDAO.insertSelective(changeHistoryCriteria);
    }

    @Override
    public List<BaseLine> queryAvailableBaseline(AvailableBaselineQueryRequest availableBaselineQueryRequest)
            throws Exception {
        // List<BaseLineDO> baseLineDOs =
        // baseLineDAO.getBaselineByStauts(Constant.LogicVariable.YES_INT);

        // TODO Auto-generated method stub
        return null;
    }
}
